package com.framework.buss.bridge.service.impl;

import com.alibaba.fastjson.util.IOUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.framework.buss.bridge.model.WordByte;
import com.framework.buss.bridge.model.WordTree;
import com.framework.buss.bridge.model.WordTreeSelected;
import com.framework.buss.bridge.mapper.WordByteMapper;
import com.framework.buss.bridge.mapper.WordTreeSelectedMapper;
import com.framework.buss.bridge.service.IWordByteService;
import com.framework.buss.bridge.service.IWordTreeSelectedService;
import com.framework.buss.bridge.service.IWordTreeService;
import com.framework.buss.bridge.vo.WordTreeIdVO;
import com.framework.buss.bridge.vo.WordTreeSelectedVO;
import com.framework.common.exception.BusinessException;
import com.framework.common.util.UUIDGenerator;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Description: AI报告word目录表
 * @Author: jeecg-boot
 * @Date:   2023-08-16
 * @Version: V1.0
 */
@Log4j2
@Service
public class WordTreeSelectedServiceImpl extends ServiceImpl<WordTreeSelectedMapper, WordTreeSelected> implements IWordTreeSelectedService {
	@Value("${jeecg.path.data:/}")
	private String path;

	@Autowired
	private IWordTreeService wordTreeService;
	@Autowired
	private WordByteMapper wordByteMapper;
	@Autowired
	private IWordByteService wordByteService;

	@Override
	public WordTreeSelected findOne(WordTreeSelected params) {
		String bridgeId = params.getBridgeId();
		String originId = params.getOriginId();
		if (StringUtils.isBlank(bridgeId) || StringUtils.isBlank(originId)) {
			return new WordTreeSelected();
		}
		QueryWrapper queryWrapper = new QueryWrapper();
		queryWrapper.eq("bridge_id", bridgeId);
		queryWrapper.eq("origin_id", originId);

		WordTreeSelected ret = baseMapper.selectOne(queryWrapper);

		if (ObjectUtils.isEmpty(ret)) {
			WordTree wordTree = wordTreeService.findById(originId);
			ret = new WordTreeSelected();
			BeanUtils.copyProperties(wordTree, ret);
			ret.setBridgeId(bridgeId);
			ret.setOriginId(originId);
			ret.setId(null);

			baseMapper.insert(ret);
			// id自动生成了， 重新查询一遍
			ret = baseMapper.selectOne(queryWrapper);
		}

		return ret;
	}

	@Override
	public void loadWord(HttpServletRequest request, HttpServletResponse response) {
		String fileId = request.getParameter("id");
		QueryWrapper wrapper = new QueryWrapper<>();
		wrapper.eq("file_id", fileId);

		boolean exists = wordByteMapper.exists(wrapper);
		if (!exists) {
			fileId = request.getParameter("originId");
		}
		wordByteService.loadWord(fileId, response);
	}

	@Override
	public void mergeWord(HttpServletRequest request, HttpServletResponse response) {
		String bridgeId = request.getParameter("bridgeId");
		// 查询所有数据
		QueryWrapper wrapper = new QueryWrapper<>();
		wrapper.eq("bridge_id", bridgeId);
		List<WordByte> wordBytes = wordByteMapper.selectList(wrapper);

		// 查询出当前桥梁选择的所有文档目录，目的是将文档排序后合并
		WordTreeSelectedVO params1 = new WordTreeSelectedVO();
		params1.setBridgeId(bridgeId);
		List<WordTreeSelectedVO> tree = wordTreeService.listAll(params1);

		// 根据树先序遍历排序
		List<WordByte> list = getChildren(tree, wordBytes);
		// 合并
		NiceXWPFDocument document = null;
		for (int i=0; i<list.size(); i++) {
			WordByte it = list.get(i);
			ByteArrayInputStream inputStream = null;
			NiceXWPFDocument sub = null;
			try {
				inputStream = new ByteArrayInputStream(it.getData());
				if (i == 0) {
					document = new NiceXWPFDocument(inputStream);
				} else {
					XWPFParagraph p = document.createParagraph();
					p.setPageBreak(true);
					sub = new NiceXWPFDocument(inputStream);
					// 每次出来的都是新的
					document = document.merge(sub);
				}
			} catch (Exception e) {
				log.error("文件合并失败");
			} finally {
				if (null != inputStream) {
					IOUtils.close(inputStream);
				}
				if (null != sub) {
					IOUtils.close(sub);
				}
			}
		}

		// 合并后写入数据库
		FileOutputStream os = null;
		String id = UUIDGenerator.generate();
		String temp = path + "/data/"+id + ".docx";
		try {
			File file = new File(temp);
			file.createNewFile();
			os = new FileOutputStream(file);
			document.write(os);
		} catch (IOException e) {
			log.error("文件合并失败");
			throw new BusinessException("文件合并失败");
		} finally {
			if (null != document) {
				IOUtils.close(document);
			}
			if (null != os) {
				IOUtils.close(os);
			}
		}

		wordByteService.readFile(temp, bridgeId);
	}

	private List<WordByte> getChildren(List<WordTreeSelectedVO> tree, List<WordByte> wordBytes) {
		List<WordByte> sortWordBytes = new ArrayList<>();
		tree.forEach(it -> {
			Optional<WordByte> optional = wordBytes.stream().filter(item -> item.getFileId().equals(it.getId())).findFirst();
			if (optional.isPresent()) {
				sortWordBytes.add(optional.get());
			}
			if (!ObjectUtils.isEmpty(it.getChildren())) {
				List<WordByte> children = getChildren(it.getChildren(), wordBytes);
				sortWordBytes.addAll(children);
			}
		});

		return sortWordBytes;
	}


	@Override
	public void addWordTreeSelected(WordTreeIdVO idVO) {
		List<WordTree> list = wordTreeService.findByIds(idVO.getIdList());
		String bridgeId = idVO.getBridgeId();

		WordTreeSelected params = new WordTreeSelected();
		params.setBridgeId(bridgeId);
		List<WordTreeSelected> selectedList = baseMapper.findSelectedIdList(params);
		List<String> existsIdList = selectedList.stream().map(it->it.getOriginId()).collect(Collectors.toList());

		list.forEach(item -> {
			if (existsIdList.contains(item.getId())) {
				existsIdList.remove(item.getId());
				return;
			}
			WordTreeSelected it = new WordTreeSelected();
			BeanUtils.copyProperties(item, it);
			it.setBridgeId(bridgeId);
			it.setOriginId(item.getId());
			it.setId(null);

			baseMapper.insert(it);
		});

		if (existsIdList.size() > 0) {
			// 删除取消勾选的数据
			selectedList = selectedList.stream().filter(it -> existsIdList.contains(it.getOriginId())).collect(Collectors.toList());
			List<String> removeList = selectedList.stream().map(it->it.getId()).collect(Collectors.toList());
			baseMapper.deleteBatchIds(removeList);

			// 删除word模板
			removeList.forEach(it -> {
				QueryWrapper queryWrapper = new QueryWrapper();
				queryWrapper.eq("file_id", it);
				wordByteMapper.delete(queryWrapper);
			});
		}
	}

	@Override
	public List<String> getSelectedIdList(String bridgeId) {
		WordTreeSelected params = new WordTreeSelected();
		params.setBridgeId(bridgeId);
		List<WordTreeSelected> list = baseMapper.findSelectedIdList(params);
		// 这里通过原始模板的id进行选择
		List<String> ret = list.stream().map(it->it.getOriginId()).collect(Collectors.toList());

		return ret;
	}

}
